package com.gitee.qdbp.general.system.biz.personnel.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.gitee.qdbp.able.beans.Duration.Second;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.able.result.ResultCode;
import com.gitee.qdbp.general.common.api.sms.service.ISmsService;
import com.gitee.qdbp.general.system.biz.personnel.service.impl.Constants.CacheKeys;
import com.gitee.qdbp.general.system.error.UserErrorCode;
import com.gitee.qdbp.tools.cache.ICacheService;
import com.gitee.qdbp.tools.utils.RandomTools;
import com.gitee.qdbp.tools.utils.StringTools;
import com.gitee.qdbp.tools.utils.VerifyTools;

/**
 * 邮箱验证码
 *
 * @author zhaohuihua
 * @version 180612
 */
@Service
public class EmailValidCodeService {

    /** 日志对象 **/
    private static final Logger log = LoggerFactory.getLogger(EmailValidCodeService.class);

    @Autowired
    private ICacheService cache;
    @Autowired
    private ISmsService smsService;

    public void sendLoginValidCode(String email) throws ServiceException {
        String msg = "Failed to SendLoginCode. ";
        checkEmail(email, msg);

        // 获得验证码
        String validCode = RandomTools.generateNumber(4);

        // 存入缓存
        // 缓存时间(单位:秒)
        int time = smsService.getCacheTime(Constants.EmailTemplate.login);
        cache.set(CacheKeys.VALID_CODE_LOGIN.name(), email, validCode, new Second(time));

        // 验证码：@1@，@2@分钟内有效。
        smsService.send(email, Constants.EmailTemplate.login, validCode, time / 60);
    }

    public void checkLoginValidCode(String email, String validCode, boolean remove) throws ServiceException {
        String msg = "Failed to CheckLoginCode. ";
        checkEmail(email, msg);
        if (VerifyTools.isBlank(validCode)) {
            log.error(msg + "params is null: validCode");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 获得验证码
        if (!cache.exist(CacheKeys.VALID_CODE_LOGIN.name(), email)) {
            throw new ServiceException(UserErrorCode.USER_EMAIL_VALID_CODE_EXPIRED);
        }
        if (!validCode.equals(cache.get(CacheKeys.VALID_CODE_LOGIN.name(), email, String.class))) {
            throw new ServiceException(UserErrorCode.USER_EMAIL_VALID_CODE_ERROR);
        }
        if (remove) {
            cache.del(CacheKeys.VALID_CODE_LOGIN.name(), email);
        }
    }

    public void sendRegisterValidCode(String email) throws ServiceException {
        String msg = "Failed to SendRegisterCode. ";
        checkEmail(email, msg);

        // 获得验证码
        String validCode = RandomTools.generateNumber(4);

        // 存入缓存
        // 缓存时间(单位:秒)
        int time = smsService.getCacheTime(Constants.EmailTemplate.register);
        cache.set(CacheKeys.VALID_CODE_REGISTER.name(), email, validCode, new Second(time));

        // 验证码：@1@，@2@分钟内有效。
        smsService.send(email, Constants.EmailTemplate.register, validCode, time / 60);
    }

    public void checkRegisterValidCode(String email, String validCode, boolean remove) throws ServiceException {
        String msg = "Failed to CheckRegisterCode. ";
        checkEmail(email, msg);
        if (VerifyTools.isBlank(validCode)) {
            log.error(msg + "params is null: validCode");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 获得验证码
        if (!cache.exist(CacheKeys.VALID_CODE_REGISTER.name(), email)) {
            throw new ServiceException(UserErrorCode.USER_EMAIL_VALID_CODE_EXPIRED);
        }
        if (!validCode.equals(cache.get(CacheKeys.VALID_CODE_REGISTER.name(), email, String.class))) {
            throw new ServiceException(UserErrorCode.USER_EMAIL_VALID_CODE_ERROR);
        }
        if (remove) {
            cache.del(CacheKeys.VALID_CODE_REGISTER.name(), email);
        }
    }

    public void sendRepasswordValidCode(String email) throws ServiceException {
        String msg = "Failed to SendRepasswordCode. ";
        checkEmail(email, msg);

        // 获得验证码
        String validCode = RandomTools.generateNumber(4);

        // 存入缓存
        // 缓存时间(单位:秒)
        int time = smsService.getCacheTime(Constants.EmailTemplate.repassword);
        cache.set(CacheKeys.VALID_CODE_REPASSWORD.name(), email, validCode, new Second(time));

        // 验证码：@1@，@2@分钟内有效。
        smsService.send(email, Constants.EmailTemplate.repassword, validCode, time / 60);
    }

    public void checkRepasswordValidCode(String email, String validCode, boolean remove) throws ServiceException {
        String msg = "Failed to CheckRepasswordCode. ";
        checkEmail(email, msg);
        if (VerifyTools.isBlank(validCode)) {
            log.error(msg + "params is null: validCode");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 获得验证码
        if (!cache.exist(CacheKeys.VALID_CODE_REPASSWORD.name(), email)) {
            throw new ServiceException(UserErrorCode.USER_EMAIL_VALID_CODE_EXPIRED);
        }
        if (!validCode.equals(cache.get(CacheKeys.VALID_CODE_REPASSWORD.name(), email, String.class))) {
            throw new ServiceException(UserErrorCode.USER_EMAIL_VALID_CODE_ERROR);
        }
        if (remove) {
            cache.del(CacheKeys.VALID_CODE_REPASSWORD.name(), email);
        }
    }

    public void sendChangePhoneValidCode(String email) throws ServiceException {
        String msg = "Failed to SendChangePhoneCode. ";
        checkEmail(email, msg);

        // 获得验证码
        String validCode = RandomTools.generateNumber(4);

        // 存入缓存
        // 缓存时间(单位:秒)
        int time = smsService.getCacheTime(Constants.EmailTemplate.change_email);
        cache.set(CacheKeys.VALID_CODE_CHANGE_PHONE.name(), email, validCode, new Second(time));

        // 验证码：@1@，@2@分钟内有效。
        smsService.send(email, Constants.EmailTemplate.change_email, validCode, time / 60);
    }

    public void checkChangeEmailValidCode(String email, String validCode, boolean remove) throws ServiceException {
        String msg = "Failed to CheckChangePhoneCode. ";
        checkEmail(email, msg);
        if (VerifyTools.isBlank(validCode)) {
            log.error(msg + "params is null: validCode");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        if (!cache.exist(CacheKeys.VALID_CODE_CHANGE_PHONE.name(), email)) {
            throw new ServiceException(UserErrorCode.USER_EMAIL_VALID_CODE_EXPIRED);
        }
        if (!validCode.equals(cache.get(CacheKeys.VALID_CODE_CHANGE_PHONE.name(), email, String.class))) {
            throw new ServiceException(UserErrorCode.USER_EMAIL_VALID_CODE_ERROR);
        }
        if (remove) {
            cache.del(CacheKeys.VALID_CODE_REPASSWORD.name(), email);
        }
    }

    protected void checkEmail(String email, String msg) throws ServiceException {
        if (VerifyTools.isBlank(email)) {
            log.error(msg + "params is null: email");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (!StringTools.isEmail(email)) {
            log.error(msg + "email format error: {}", email);
            throw new ServiceException(UserErrorCode.EMAIL_FORMAT_ERROR);
        }
    }

}
